#include "CardRW.h"
#include "ui_CardRW.h"
#include "openssl/des.h"
#include "Algorithm.h"
#include <QRegExp>

#include "idcardread.h"

CardRW::CardRW(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CardRW)
{
    ui->setupUi(this);

    QRegExp regx("[0-9]+$"); //限制只能输入数字
    QValidator *valiNum = new QRegExpValidator(regx);

    ui->leXieYinHangKaHao2->setValidator(valiNum);
    //ui->leXieShenFenZhengHao->setValidator(valiNum);
    ui->leXieDianHua->setValidator(valiNum);
}

void CardRW::idcRcv(IdCData idd)
{
    if (ui->leXieShenFenZhengHao->text().isEmpty())
    {
        ui->leXieShenFenZhengHao->setText(idd["id"]);
    }

    QString sex = ui->leXieXingBie->currentText();
    QString isex = idd["sex"];

    if (sex != isex && !isex.isEmpty())
    {
        ui->leXieXingBie->setCurrentText(isex);
    }

    if (ui->leXieXingMing->text().isEmpty())
    {
        ui->leXieXingMing->setText(idd["name"]);
    }
}

CardRW::~CardRW()
{
    delete ui;
}

void CardRW::ShowDuKa(QByteArray &data)
{
    QString str;
    QMap<QString, QString> val;

    if (data.size() < 16)
        return;

    getValues(data, val);

    ui->leDuYinHangKaHao->setText(val["卡号"]);
    ui->leDuXingMing->setText(val["姓名"]);
    ui->leDuXingBie->setText(val["性别"]);
    ui->leDuShengFenZhengHao->setText(val["身份"]);
    ui->leDuZhuanMaiZhengHao->setText(val["专卖"]);
    ui->leDuDianHua->setText(val["电话"]);
    ui->leDuDiZhi->setText(val["地址"]);
}

bool CardRW::SFZHValid(QString sfz)
{
    int weight[]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    char validate[]={ '1','0','X','9','8','7','6','5','4','3','2'};
    int sum=0;
    int mode=0;

    if (sfz.length()==18)
    {
        for(int i=0;i<sfz.length()-1;i++)
        {
            sum=sum+(sfz.toStdString().at(i)-'0')*weight[i];
        }
        mode=sum%11;
        if (validate[mode]==sfz[17])
        {
            return true;
        }
    }

    return false;
}

bool CardRW::GetInfo(QByteArray &data, QByteArray &keyb, QByteArray &blk3, int &mode)
{
    QByteArray buf;
    int len;
    QByteArray nkey;
    QString str;

    str = ui->leXieYinHangKaHao2->text();
    if (str.length() < 16)
    {
        statustip = "请输入正确的卡号";
        return false;
    }

    buf += Algorithm::toBCD(str);
    str = ui->leXieXingMing->text();
    if (str.isEmpty())
    {
        statustip = "请输入姓名";
        return false;
    }
    buf += makeItem(1, str);
    str = ui->leXieShenFenZhengHao->text();
    if (!SFZHValid(str))
    {
        statustip = "请输入身份证号";
        return false;
    }
    buf += makeItem(2, str);
    buf += makeItem(3, ui->leXieXingBie->currentText());
    str = ui->leXieZhuanMaiZhengHao->text();
    if (str.length() < 8)
    {
        statustip = "请输入专卖证号";
        return false;
    }
    buf += makeItem(4, str);
    str = ui->leXieDianHua->text();
    if (str.length() < 11)
    {
        statustip = "请输入电话";
        return false;
    }
    buf += makeItem(5, str);
    str = ui->leXieDiZhi->text();
    if (str.length() < 2)
    {
        statustip = "请输入地址";
        return false;
    }
    buf += makeItem(6, str);

    if (buf.size() % 16 != 0)
    {
        len = (buf.size() + 15)/16 * 16;
        data.resize(len - buf.size());
        data.fill(0, len - buf.size());
        buf += data;
    }

    data = buf;

    GetKeyB(keyb);

    if (ui->leDuYinHangKaHao->text().isEmpty())
    {
        mode = 3;
    }
    else if (ui->leDuXingMing->text().isEmpty())
    {
        mode = 1;
    }
    else
    {
        mode = 2;
    }

    if(GetSpecKeyB(nkey))
    {
        blk3.resize(10);
        blk3.fill(0, 10);
        blk3.data()[6] = 0x78;
        blk3.data()[7] = 0x77;
        blk3.data()[8] = 0x88;
        blk3.data()[9] = 0x00;
        blk3 += keyb;

        keyb = nkey;
        mode = 3;
    }

    return true;
}

QByteArray CardRW::makeItem(char type, QString str)
{
    QByteArray buf(3, 93);
    QByteArray data;
    char mi = 93;

    encrypt(data, mi, str);
    buf[0] = data.length();
    buf[1] = type;
    buf[2] = mi;
    buf += data;

    return buf;
}

void CardRW::encrypt(QByteArray &out, char mi, QString str)
{
    char temp;
    char *buf;

    out = str.toStdString().c_str();
    buf = out.data();
    for (int i = 0; i < out.length() - 1; i += 2)
    {
        temp = buf[i];
        buf[i] = buf[i + 1];
        buf[i + 1] = temp;
    }

    mi += 128;

    for (int i = 0; i < out.length(); i++)
    {
        buf[i] += 67 * i + i * i * mi;
    }
}

void CardRW::decrypt(QByteArray data, char mi, QString &val)
{
    char *buf = data.data();

    mi += 128;

    for (int i = 0; i < data.length(); i++)
    {
        buf[i] -= 67 * i + i * i * mi;
    }

    for (int i = 0; i < data.length() - 1; i += 2)
    {
        char tmp;

        tmp = buf[i];
        buf[i] = buf[i+1];
        buf[i+1] = tmp;
    }

    val = data;
}

void CardRW::getValues(QByteArray &data, QMap<QString, QString> &val)
{
    char len;
    char type;
    char mi;
    int pos = 16;
    int cnt = 0;

    val["卡号"] = Algorithm::fromBCD(data);

    while (pos < data.count())
    {
        QString str;

        if ((pos+3) > data.count())
            break;

        len = data.at(pos++);
        type = data.at(pos++);
        mi = data.at(pos++);

        if (type <= 0 || type > 6)
            break;
        if (len == 0)
            continue;

        if ((pos+len) > data.count())
            break;

        decrypt(data.mid(pos, len), mi, str);
        pos += len;

        switch (type)
        {
        case 1:
        {
            val["姓名"] = str;
            cnt ++;
        }break;
        case 2:
        {
            val["身份"] = str;
            cnt ++;
        }break;
        case 3:
        {
            val["性别"] = str;
            cnt ++;
        }break;
        case 4:
        {
            val["专卖"] = str;
            cnt ++;
        }break;
        case 5:
        {
            val["电话"] = str;
            cnt ++;
        }break;
        case 6:
        {
            val["地址"] = str;
            cnt ++;
        }break;
        }

        if (cnt == 6)
            break;
    }
}

bool CardRW::GetSpecKeyB(QByteArray &keyb)
{
    if (ui->ZhiDingMiYue->isChecked())
    {
        keyb = Algorithm::toByte(ui->MiYue->currentText());

        return true;
    }

    return false;
}

/*
  从要写入的卡号中计算密钥
*/
void CardRW::GetKeyB(QByteArray &keyb)
{
    QString kahao;

    kahao = ui->leXieYinHangKaHao2->text();

    Algorithm::calcKeyB(kahao, keyb);
}

void CardRW::Clear()
{
    ui->leDuYinHangKaHao->clear();
    ui->leDuXingMing->clear();
    ui->leDuXingBie->clear();
    ui->leDuShengFenZhengHao->clear();
    ui->leDuZhuanMaiZhengHao->clear();
    ui->leDuDianHua->clear();
    ui->leDuDiZhi->clear();

    ui->leXieYinHangKaHao2->clear();
    ui->leXieXingMing->clear();

    ui->leXieShenFenZhengHao->clear();
    ui->leXieZhuanMaiZhengHao->clear();
    ui->leXieDianHua->clear();
    ui->leXieDiZhi->clear();
}

void CardRW::on_pbDuKa_clicked()
{
    Clear();

    emit pbEvent(2);
}

void CardRW::on_pbXieKa_clicked()
{
    emit pbEvent(3);
}
